﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using Citrix.Cmp;
using Citrix.XaAdminMobile.Util;
using System.IO;
using System.Diagnostics;

namespace Citrix.XaAdminMobile
{
    /// <summary>
    /// The main app class.
    /// </summary>
    public partial class App : Application
    {
        /// <summary>
        /// Application.Current can return null and it is typed to the base Application class.
        /// So we store our own typed ref for accessing the app object.
        /// </summary>
        private static App thisRef;

        /// <summary>
        /// Base CMP .NET API.
        /// </summary>
        private CmpApi cmpApi;

        /// <summary>
        /// WPF specific CMP API.
        /// </summary>
        private CmpWpfApi wpfCmpApi;

        /// <summary>
        /// Used to keep the CMP state synced to how the app wants it.
        /// </summary>
        private CmpSynchroniser cmpSync;

        /// <summary>
        /// This is the reference DPI the app was designed for. The DPI scaling is done relative
        /// to this DPI.
        /// </summary>
        private const int ReferenceAppDpi = 163;

        /// <summary>
        /// The root object for the model layer.
        /// </summary>
        private readonly Model.IModelBase modelBase;

        /// <summary>
        /// The root object for the view-model layer.
        /// </summary>
        private readonly ViewModel.ViewModelManager vmMgr;

        /// <summary>
        /// Default ctor.
        /// </summary>
        public App()
        {
            thisRef = this;

            this.Exit += new ExitEventHandler(App_Exit);

            //
            // Setup diagnostic trace capture.
            //
            //string dir = GetLogFilePath();
            //if (!Directory.Exists(dir))
            //{
            //    Directory.CreateDirectory(dir);
            //}
            //string logFilename = Path.Combine(dir, "GoldenGate.log");
            //var listener = new TimestampTextFileTraceListener(logFilename);
            //Trace.Listeners.Add(listener);

            this.cmpApi = new CmpApi();
            this.wpfCmpApi = new CmpWpfApi(this.cmpApi, new ReferenceDpi(ReferenceAppDpi, ReferenceAppDpi));
            Citrix.Cmp.AutoWindowLayout.DefaultWindowSize = new Size(1024, 768);
            this.cmpSync = new CmpSynchroniser(this, this.cmpApi);

            this.modelBase = Citrix.XaAdminMobile.Model.ModelFactory.Create();
            this.vmMgr = new Citrix.XaAdminMobile.ViewModel.ViewModelManager(this, this.modelBase);
        }

        /// <summary>
        /// Static, typed app object getter.
        /// </summary>
        public static App TypedApp
        {
            get { return thisRef; }
        }

        /// <summary>
        /// The local CMP state manager we use to help keep the CMP state on the client in sync
        /// with what we want.
        /// </summary>
        internal CmpSynchroniser CmpSynchroniser
        {
            get { return this.cmpSync; }
        }

        /// <summary>
        /// The CMP WPF API object.
        /// </summary>
        internal CmpWpfApi CmpWpfApi
        {
            get { return this.wpfCmpApi; }
        }

        /// <summary>
        /// Dispatches a work item to be executed asynchronously on the UI thread.
        /// </summary>
        /// <param name="action">The work item.</param>
        internal void Dispatch(Action action)
        {
            if (null != action)
            {
                this.Dispatcher.BeginInvoke(action);
            }
        }

        /// <summary>
        /// Returns the base object in the model layer.
        /// </summary>
        internal Citrix.XaAdminMobile.Model.IModelBase Model
        {
            get { return this.modelBase; }
        }

        /// <summary>
        /// Returns the base object in the view-model layer.
        /// </summary>
        internal Citrix.XaAdminMobile.ViewModel.ViewModelManager ViewModel
        {
            get { return this.vmMgr; }
        }

        /// <summary>
        /// App Exit event handler.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void App_Exit(object sender, ExitEventArgs e)
        {
            if (null != this.cmpApi)
            {
                this.cmpApi.Dispose();
            }
            if (null != this.modelBase)
            {
                this.modelBase.Dispose();
            }
        }
    }
}
